package roborally.program;

import be.kuleuven.cs.som.annotate.*;

/**
 * A class for dealing with the elements of a program
 * (commands and conditions), involving a line number.
 * 
 * @invar	The line number of each program element must be a valid 
 * 			line number.
 *          | canHaveAsLineNb(getLineNb())       
 * 
 * @version	1.0
 * @author  Pieter Robberechts	(1e Bach Informatica)
 * @author	Jeroen Sanders		(1e Bach Informatica)
 *
 */
public abstract class ProgramElement {

	/**
	 * Initialize this new program element with given line number.
	 * 
	 * @param 	lineNb
	 * 			The line number for this program element.
	 * @pre		The given line number must be a valid one.
	 * 			| canHaveAsLineNb(lineNb)
	 * @post	The line number of this program element is set to 
	 * 			the given line number.
	 * 			| new.getLineNb() == lineNb
	 */
	public ProgramElement(int lineNb) {
		assert(canHaveAsLineNb(lineNb));
		this.lineNb = lineNb;
	}
	
	/**
	 * Variable registering the line number of this program element.
	 */
	private final int lineNb;
	
	/**
	 * Return the line number of this program element.
	 */
	@Basic @Raw @Immutable
	public int getLineNb() {
		return lineNb;
	}
	
	/**
	 * Check whether the given line number is a valid one.
	 * 
	 * @param 	lineNb
	 * 			The line number to check for whether it is valid
	 * @return	Return true if and only if the given line number is a value 
	 * 			between zero (exclusive) and Integer.MAX_VALUE (inclusive).
	 * 			| result == ( lineNb > 0 && lineNb <= Integer.MAX_VALUE )
	 */
	@Raw
	public boolean canHaveAsLineNb(int lineNb) {
		return lineNb > 0 && lineNb <= Integer.MAX_VALUE;
	}

	/**
	 * Return a textual representation of this program element,
	 * formatted in accordance with its position in the program.
	 * 
	 * @param 	indentationLevel
	 * 			The level of indentation for this program element,
	 * 			relative to the program.
	 */
	public abstract String prettyFormat(int indentationLevel);
	
	/**
	 * Return the string-based version of a given indentation level.
	 * 
	 * @param 	indentationLevel
	 * 			The numeric representation of an indentation level
	 * @return	Return a string consisting of '2*indentationLevel' spaces.
	 * 			| ...
	 */
	public String getIndentation(int indentationLevel) {
		String indentation = "";
		while(indentationLevel > 0) {
			indentation += "  ";
			indentationLevel--;
		}
		return indentation;
	}
}
